home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 109 / EnigmaAmiga109CD.iso / dalla rivista / amiga.free / sorgenti vari / wolf3dmacsource.sit / Wolf3DMacSource / Missiles.c < prev    next >
C/C++ Source or Header  |  1994-09-20  |  5KB  |  194 lines

  1. #include "wolfdef.h"
  2.  
  3. /**********************************
  4.  
  5.     Returns a pointer to an empty missile record
  6.     
  7. **********************************/
  8.  
  9. missile_t *GetNewMissile(void)
  10. {
  11.     Word Count;
  12.  
  13.     Count = nummissiles;
  14.     if (Count < MAXMISSILES) {    /* Already full? */
  15.         ++Count;                    /* Next entry */
  16.         nummissiles = Count;        /* Save the new missile count */
  17.     }
  18.     return &missiles[Count-1];    /* Get pointer to empty missile */
  19. }
  20.  
  21. /**********************************
  22.  
  23.     Explode a missile
  24.     
  25. **********************************/
  26.  
  27. void ExplodeMissile(missile_t *MissilePtr)
  28. {
  29.     MissilePtr->flags = 0;        /* Can't harm anyone! */
  30.     if (MissilePtr->type == MI_PMISSILE) {
  31.         MissilePtr->pic = S_MISSBOOM;    /* Rocket explosion */
  32.         MissilePtr->type = 16;        /* Tics to stay in explosion*/
  33.     } else {
  34.         MissilePtr->pic = S_FIREBOOM;    /* Fire explosion */
  35.         MissilePtr->type = 8;        /* Tics to stay in explosion*/
  36.     }
  37.     PlaySound(SND_BOOM|0x8000);            /* BOOM! */
  38.     MissilePtr->x -= MissilePtr->xspeed;    /* Undo the last motion */
  39.     MissilePtr->y -= MissilePtr->yspeed;
  40.     MissilePtr->xspeed = 0;            /* Don't move anymore */
  41.     MissilePtr->yspeed = 0;
  42. }
  43.  
  44. /**********************************
  45.  
  46.     Take damage from the player
  47.     Damage is 8,16...64, pass the x,y for a kill x,y
  48.     
  49. **********************************/
  50.  
  51. void MissileHitPlayer(missile_t *MissilePtr)
  52. {
  53.     TakeDamage((w_rnd()&0x38)+8,MissilePtr->x,MissilePtr->y);    /* Inflict damage */
  54. }
  55.  
  56. /**********************************
  57.  
  58.     Take damage from the enemy
  59.     Detonate if not killed (return True)
  60.     
  61. **********************************/
  62.  
  63. Boolean MissileHitEnemy(missile_t *MissilePtr, actor_t *ActorPtr)
  64. {
  65.     Word Damage;
  66.     if (MissilePtr->type == MI_PMISSILE) {    /* Rocket? */
  67.         Damage = (w_rnd()&0x30)+16;    /* Hit'm hard! */
  68.     } else {
  69.         Damage = (w_rnd()&0x0f)+1;    /* Burn a little */
  70.     }
  71.     DamageActor(Damage,ActorPtr);    /* Hit'em! */
  72.     return !(ActorPtr->flags & FL_DEAD);     /* Not dead? */
  73. }
  74.  
  75. /**********************************
  76.  
  77.     Did the missile impact on an actor
  78.     
  79. **********************************/
  80.  
  81. Boolean CheckMissileActorHits(missile_t *MissilePtr)
  82. {
  83.     Word xl,xh,yh;
  84.     Word x,y;
  85.     Word Bang;
  86.     Word tile;
  87.     actor_t *ActorPtr;
  88.     
  89.     Bang = 0;            /* Assume the missile is OK */
  90.     xl = (MissilePtr->x>>FRACBITS)-1;    /* Create the kill rect */
  91.     xh = xl+3;
  92.     y = (MissilePtr->y>>FRACBITS)-1;
  93.     yh = y+3;    
  94.     if (xl>=MAPSIZE) {        /* Clip the attack rect to STAY on the map! */
  95.         xl = 0;
  96.     }
  97.     if (y>=MAPSIZE) {
  98.         y = 0;
  99.     }
  100.     if (xh>=MAPSIZE) {
  101.         xh = MAPSIZE;
  102.     }
  103.     if (yh>=MAPSIZE) {
  104.         yh = MAPSIZE;
  105.     }
  106.     do {
  107.         x = xl;        /* Begin the X scan */
  108.         do {
  109.             tile = tilemap[y][x];    /* Actor here? */
  110.             if (tile&TI_ACTOR) {
  111.                 ActorPtr = &actors[MapPtr->tilemap[y][x]];    /* Check for impact */
  112.                 if ( (w_abs(ActorPtr->x - MissilePtr->x) < MISSILEHITDIST) &&
  113.                     (w_abs(ActorPtr->y - MissilePtr->y) < MISSILEHITDIST)) {
  114.                     Bang |= MissileHitEnemy(MissilePtr,ActorPtr); /* Detonate? */
  115.                 }
  116.             }
  117.         } while (++x<xh);    /* Scan the x's */
  118.     } while (++y<yh);        /* Scan the y's */
  119.     return Bang;    /* Return detonation value */
  120. }
  121.  
  122. /**********************************
  123.  
  124.     Move the missiles each game frame
  125.     
  126. **********************************/
  127.  
  128. void MoveMissiles(void)
  129. {
  130.     Word Count;        /* Current missile # */
  131.     missile_t *MissilePtr;    /* Pointer to missile record */
  132.     Word i,x,y,tile;        /* Tile position */
  133.     
  134.     Count = nummissiles;    /* How many active missiles? */
  135.     if (!Count || !TicCount) {        /* No missiles? (Or elapsed time?) */
  136.         return;                /* Exit now */
  137.     }
  138.     
  139.     MissilePtr = &missiles[0];    /* Init pointer to the first missile */
  140.     do {    
  141.         if (!MissilePtr->flags) {    /* inert explosion*/
  142.             if (MissilePtr->type>TicCount) {    /* Time up? */
  143.                 MissilePtr->type-=TicCount;        /* Remove some time */
  144.                 ++MissilePtr;            /* Go to the next entry */
  145.             } else {
  146.                 --nummissiles;        /* Remove this missile */
  147.                 MissilePtr[0] = missiles[nummissiles];    /* Copy the FINAL record here */
  148.             }    
  149.             continue;        /* Next! */
  150.         }
  151.         
  152.     /* move position*/
  153.     
  154.         i = TicCount;        /* How many times to try this? */
  155.         do {
  156.             MissilePtr->x += MissilePtr->xspeed;
  157.             MissilePtr->y += MissilePtr->yspeed;
  158.         
  159.     /* check for contact with player*/
  160.     
  161.             if (MissilePtr->flags & MF_HITPLAYER) {
  162.                 if (w_abs(MissilePtr->x - actors[0].x) < MISSILEHITDIST
  163.                 && w_abs(MissilePtr->y - actors[0].y) < MISSILEHITDIST) {
  164.                     MissileHitPlayer(MissilePtr);        /* Take damage */
  165.                     goto BOOM;            /* Boom! */
  166.                 }            
  167.             }
  168.         
  169.     /* check for contact with actors*/
  170.     
  171.             if (MissilePtr->flags & MF_HITENEMIES) {
  172.                 if (CheckMissileActorHits(MissilePtr)) {    /* Did it detonate? */
  173.                     goto BOOM;                /* Boom! */
  174.                 }
  175.             }
  176.         
  177.     /* check for contact with walls and get new area */
  178.     
  179.             x = MissilePtr->x >> FRACBITS;
  180.             y = MissilePtr->y >> FRACBITS;
  181.             tile = tilemap[y][x];
  182.             if (tile & TI_BLOCKMOVE) {        /* Can be a solid static or a wall*/
  183. BOOM:
  184.                 ExplodeMissile(MissilePtr);    /* Detonate a missile */
  185.                 break;
  186.             }
  187.             if (!(tile&TI_DOOR) ) { /* doorways don't have real area numbers*/
  188.                 MissilePtr->areanumber = tile&TI_NUMMASK;
  189.             }
  190.         } while (--i);
  191.         ++MissilePtr;        /* Pointer to the next entry */
  192.     } while (--Count);    /* No more entries? */
  193. }
  194.